import { useEffect, useRef, useState } from 'react';
import i18n from '@app-cad/common/utils/i18next';
import {
  BaseCommand,
  CommandDialog,
  pickedModelData,
  pickedVertexData,
  FeatureManager,
} from '@amcax/base';
import { docMgr } from '@app-base/module';
import { wsApi } from '@app-base/server';
import { CommandLabeledItemWrapper } from '@app-cad/common/components/command-form/item-wrapper';
import CmdInteractor from './CmdInteractor';
import {
  MultiPickInput,
  PickInputValueType,
} from '@app-base/common/components/pick-input/3d';
import { useCommand } from '@app-base/common/hooks/useCommand';
import { CommandFormFooter } from '@app-base/common/components/command-form/footer';
import { ComCommand } from './component';
import { defaultEventCenter } from '@app-base/common/events/DefaultEventCenter';
import { removePoint } from './base';
import { Select } from 'antd';
function PointAxis({ onClose, title }) {
  defaultEventCenter().setState('cmd-free-point');
  const { confirmCommand, clear, isLoading, isPreviewLoading } = useCommand(
    'cmd-free-point',
    {
      commandName: 'CreateVertex',
      onClose,
      finishDraw: checkAndFinishDraw,
    },
  );
  const [param, setParam] = useState<any>();
  const cmdRef = useRef<CmdInteractor>(null);
  const [active, setActive] = useState<number>(0);
  useEffect(() => {
    cmdRef.current = new CmdInteractor({ setParam, setActive });
    cmdRef.current.addExit(onClose);
    setActive(1);
    return () => {
      cmdRef.current?.destroy();
      cmdRef.current = null;
    };
  }, []);
  const [pickedPoint, setPickedPoint] = useState<pickedVertexData>(null);
  const [pickedAxis, setPickedAxis] = useState<pickedModelData>(null);
  const [isExecuted, setIsExecuted] = useState<boolean>(false);
  async function checkAndFinishDraw() {
    if (!isFormDataValid()) return;
    await executeFn(false);
    onClose();
  }
  const remove = () => {
    setParam((state) => ({
      ...state,
      elecPoint: {
        name: '',
        entityId: '',
        point: null,
      },
    }));
    cmdRef.current.removeByFormKey('elecPoint');
    removePoint();
  };
  const wireNames = JSON.parse(localStorage.getItem('elecWireNames') || '[]');
  const wireOptions = JSON.parse(
    localStorage.getItem('elecWireOptions') || '[]',
  );
  const [selectWireName, setSelectWireName] = useState<string>(
    wireNames?.[0] || '',
  );
  const [selectWireOption, setSelectWireOption] = useState<string>('');

  useEffect(() => {
    cmdRef.current.isPick = active === 1;
    active !== 1 && cmdRef.current.removeAssistPoint();
  }, [active, param]);
  useEffect(() => {
    setActive(1);
  });
  const isFormDataValid = () => {
    if (
      wireOptions &&
      wireOptions.length > 0 &&
      !selectWireOption &&
      wireNames &&
      wireNames.length > 0 &&
      !selectWireName
    ) {
      return false;
    }

    setIsExecuted(true);
    return true;
  };
  const setCurrentBox = async (name: string = '零件几何体.1') => {
    if (!FeatureManager.isFeatureEnabled('set-current-box')) {
      return;
    }
    let parent = docMgr.documentObjects.filter(
      (item) =>
        item.type === 'GeomBox' &&
        item.label.startsWith(name + (name === '零件几何体.1' ? '' : '点设置')),
    );
    if (!parent || parent.length <= 0) {
      await wsApi.execCmd({
        c: 'CreateGeomBox',
        name: name + (name === '零件几何体.1' ? '' : '点设置'),
      });
      parent = docMgr.documentObjects.filter(
        (item) =>
          item.type === 'GeomBox' &&
          item.label.startsWith(
            name + (name === '零件几何体.1' ? '' : '点设置'),
          ),
      );
    }
    if (parent && parent.length > 0) {
      await wsApi.execCmd({
        c: 'SetCurrentBox',
        o: parent[0].dxid,
      });
      docMgr.workingObjectDxid = parent[0].dxid;
    }
  };
  const executeFn = async (preview: boolean) => {
    const point = param?.elecPoint?.point;
    if (!point) {
      return;
    }
    const params = {
      mode: 'coordinate',
      point: point,
      origin: pickedPoint?.assisObj?.getVertex()?.toArray() || undefined,
      frame: pickedAxis || undefined,
      wireName: selectWireName,
      wireOption: selectWireOption,
    };

    await setCurrentBox(selectWireName ? selectWireName : '零件几何体.1');
    const res = await confirmCommand(
      {
        a: params,
      },
      preview,
    );
    if (res?.data?.id && selectWireOption) {
      wsApi.setLabel(res.data.id, selectWireName + '-' + selectWireOption);
    }
  };
  const preview = async () => {
    clear();
    if (!isFormDataValid()) return;
    await executeFn(true);
  };
  useEffect(() => {
    preview();
  }, [param, selectWireOption]);

  return (
    <CommandDialog
      title={title}
      onClose={onClose}
      className='antenna'
      style={{ width: '300px' }}
      placement='topLeft'>
      <div className='px_20 w_full'>
        {wireOptions && wireOptions.length > 0 && (
          <>
            <CommandLabeledItemWrapper
              className='mt-5 px-5'
              label='名称'>
              <Select
                options={wireNames.map((item) => ({
                  value: item,
                  label: item,
                }))}
                value={selectWireName}
                onChange={(val) => {
                  if (val !== selectWireName) {
                    setSelectWireName(val);
                  }
                }}
              />
            </CommandLabeledItemWrapper>
            <CommandLabeledItemWrapper
              className='mt-5 px-5'
              label='点类型'>
              <Select
                options={wireOptions.map((item) => ({
                  value: item,
                  label: item,
                }))}
                value={selectWireOption}
                onChange={(val) => {
                  if (val !== selectWireOption) {
                    setSelectWireOption(val);
                  }
                }}
              />
            </CommandLabeledItemWrapper>
          </>
        )}
        <ComCommand
          label={''}
          isActive={active === 1}
          onFocus={() => setActive(1)}
          cmdRef={cmdRef.current}
          param={param}
          relyKey={'elecPoint'}
          onChange={(value, i) => {
            setParam((state) => {
              const point = state.elecPoint.point;
              point[i] = value;
              return {
                ...state,
                elecPoint: {
                  ...state.elecPoint,
                  point,
                },
              };
            });
          }}
          onRemove={() => remove()}
        />
        <CommandLabeledItemWrapper
          label='参考点'
          className='mt_10'>
          <MultiPickInput
            active={active === 2}
            value={[pickedPoint]}
            allowPickType={[PickInputValueType.Vertex]}
            onPick={(result) => setPickedPoint(result[0])}
            onFocus={() => setActive(2)}
            placeholder='参考点(默认初始原点)'
          />
        </CommandLabeledItemWrapper>
        <CommandLabeledItemWrapper
          label='参考系'
          className='mt_10'>
          <MultiPickInput
            active={active === 3}
            value={[pickedAxis]}
            allowPickType={[PickInputValueType.Frame]}
            onPick={(result) => setPickedAxis(result[0])}
            onFocus={() => setActive(3)}
            placeholder='参考系(默认初始轴系)'
          />
        </CommandLabeledItemWrapper>
      </div>
      <div className='w_full mt_10'>
        <CommandFormFooter
          isPreviewLoading={isPreviewLoading}
          isSubmitLoading={isLoading}
          onPreview={preview}
          showPreview
          onClose={onClose}
          onSubmit={checkAndFinishDraw}
          isSubmitDisabled={!isExecuted}
          isPreviewDisabled={!isExecuted}
        />
      </div>
    </CommandDialog>
  );
}

export const cmdFreePoint: BaseCommand = {
  id: 'CmdFreePoint',
  label: 'command.freePoint',
  icon: 'commands/curved/point',
  group: 'elec',
  create: function (label: string, onClose: () => void) {
    return (
      <PointAxis
        title={i18n.t(label)}
        onClose={onClose}
      />
    );
  },
};
